let startdate = new Date();

let {intersection, difference, union, orderBy} = require("lodash-unified");
// let {getWords} = require("../utils/RegexUtils")

//用javascript Math.floor等概率的生成任意两个给定整数间的一个整数
function getRandomInt(min, max) {
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

// 例子：生成1到10之间的随机整数
let randomNum = getRandomInt(1, 10);

//任意数组就讲值放入数组，对index下标进行等概率，min max //min=0随机



let arrs = [];
for (let i = 0; i < 10; i++) {
    let aArr=[];
    for (let j = 0; j < theEng.length; j++) {
        aArr.push(Math.floor(Math.random() * 10) + 1);
    }
    arrs.push(aArr);
}

let flatedArr = arrs.reduce((previousArr, currentArr, currentIndex, array) => {
    return previousArr.concat(currentArr);
});

//使用Crypto.getRandomValues()
//方法生成更加安全的随机数。这种方法需要使用TypedArray来存储随机数，例如使用Uint8Array来生成一个0到255之间的随机整数：
//任意数组就讲值放入数组，对index下标进行等概率，min max //min=0随机
//https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=js%E9%9A%8F%E6%9C%BA%E6%95%B0&fenlei=256&rsv_pq=0xb98c2d51001ae6fd&rsv_t=fd40z6O8F%2FKxGCqU71hVs%2B3uDI5VVwVkMIE%2FPdhABntzJUFWpYegIQfBk32x&rqlang=en&rsv_dl=tb&rsv_enter=1&rsv_sug3=11&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&inputT=2558&rsv_sug4=2558

let theEng = 'The continuing tension has prompted more than half the inhabitants of the refugee camp to flee to safer areas.';
let phraseTopMost = [
    {start: {startIdx: 23, word: 'has'}, end: {startIdx: 36, word: 'more'}},
    {start: {startIdx: 51, word: 'the'}, end: {startIdx: 74, word: 'refugee'}}
]

let phraseTop1 = [
    {start: {startIdx: 0, word: 'The'}, end: {startIdx: 4, word: 'continuing'}},
    {start: {startIdx: 36, word: 'more'}, end: {startIdx: 67, word: 'of'}},
    {start: {startIdx: 87, word: 'to'}, end: {startIdx: 98, word: 'safer'}},
    {start: {startIdx: 104, word: 'areas.'}, end: {startIdx: 104, word: 'areas.'}}
]

function buildArr(phraseTop) {
    // let startdate = new Date();
    let mappedArrs = phraseTop.map((entry, index, array) => {
        let arr = [];
        for (let i = entry.start.startIdx; i < entry.end.startIdx + entry.end.word.length; i++) {
            arr.push(i);
        }
        return arr;

        // console.log(theEng.substring(arr[0],arr[arr.length-1]));
    })

    let flatedArr = mappedArrs.reduce((previousArr, currentArr, currentIndex, array) => {
        return previousArr.concat(currentArr);
    });
    let enddate = new Date();
    // console.log("ms elapsed 1:", Math.abs(startdate.getTime() - enddate.getTime()));
    // return {mappedArrs: mappedArrs, flatedArr: flatedArr}
}

let {mappedArrs: topMostMappedArrs, flatedArr: topMostReducedArr} = buildArr(phraseTopMost);
let {mappedArrs: top1MappedArrs, flatedArr: top1ReducedArr} = buildArr(phraseTop1);
// console.log()
let enddate = new Date();
console.log("ms elapsed 1:", Math.abs(startdate.getTime() - enddate.getTime()));
let topMostTop1Intersected = intersection(topMostReducedArr, top1ReducedArr);
let topMostdifferencedReduced = difference(topMostReducedArr, topMostTop1Intersected);
let top1DifferencedReduced = difference(top1ReducedArr, topMostTop1Intersected);
// [top1DifferencedReduced].findIndex((value, index, arr)=>{});

let topMostResutlArrs = [];
topMostMappedArrs.forEach(theArr => {
    let inters = intersection(theArr, topMostdifferencedReduced);
    if (inters && inters.length > 0) {
        topMostResutlArrs.push(inters);
    }
})

let top1ResutlArrs = [];
top1MappedArrs.forEach(theArr => {
    let inters = intersection(theArr, top1DifferencedReduced);
    if (inters && inters.length > 0) {
        top1ResutlArrs.push(inters);
    }
})

let topMostIntsectResultArrs = []

topMostMappedArrs.forEach(theArr => {
    let inters = intersection(theArr, topMostTop1Intersected);
    let tempArr = [];
    if (inters && inters.length > 0) {
        let i = 0;
        while (i < inters.length) {
            tempArr.push(inters[i]);
            if (inters[i + 1] !== inters[i] + 1) {
                topMostIntsectResultArrs.push(tempArr);
                tempArr = [];
            }
            i++;
        }
        // topMostIntsectResultArrs.push(inters);
    }
})


let top1IntsectResultArrs = []

top1MappedArrs.forEach(theArr => {
    let inters = intersection(theArr, topMostTop1Intersected);
    let tempArr = [];
    if (inters && inters.length > 0) {
        let i = 0;
        while (i < inters.length) {
            tempArr.push(inters[i]);
            if (inters[i + 1] !== inters[i] + 1) {
                top1IntsectResultArrs.push(tempArr);
                tempArr = [];
            }
            i++;
        }
        // topMostIntsectResultArrs.push(inters);
    }
})
enddate = new Date();
console.log("ms elapsed 2:", Math.abs(startdate.getTime() - enddate.getTime()));
let resultIntersected = union(topMostIntsectResultArrs.map(arr => arr[0] + "_" + arr[arr.length - 1]), top1IntsectResultArrs.map(arr => arr[0] + "_" + arr[arr.length - 1])).map(startEndIdx => {
    let splits = startEndIdx.split("_");
    return {
        start: parseInt(splits[0]),
        end: parseInt(splits[1]),
        type: "topMost+top1",
        text: theEng.substring(parseInt(splits[0]), parseInt(splits[1]) + 1)
    }
})
topMostResutlArrs.forEach(entry => console.log(theEng.substring(entry[0], entry[entry.length - 1] + 1)));
let topMostResultArr = topMostResutlArrs.map(entry => {
    return {
        start: entry[0],
        end: entry[entry.length - 1], type: "topMost", text: theEng.substring(entry[0], entry[entry.length - 1] + 1)
    }
});
console.log("-------------------->")
top1ResutlArrs.forEach(entry => {
    console.log(theEng.substring(entry[0], entry[entry.length - 1] + 1))
});

let top1ResultArr = top1ResutlArrs.map(entry => {
    return {
        start: entry[0],
        end: entry[entry.length - 1],
        type: "top1",
        text: theEng.substring(entry[0], entry[entry.length - 1] + 1)
    }
});
console.log("-------------------->")
resultIntersected.forEach(entry => console.log(theEng.substring(entry.start, entry.end + 1)));

let orderBy1 = orderBy(topMostResultArr.concat(top1ResultArr).concat(resultIntersected), (aa) => aa.start, "asc");

let normalArr = [];
orderBy1.forEach((entry, idx) => {
    if (idx === 0 && entry.start !== 0) {
        normalArr.push({
            start: 0,
            end: entry.start - 1, type: "normal", text: theEng.substring(0, entry.start - 1 + 1)
        })
    } else if (idx === orderBy1.length - 1 && (entry.end + 1) !== theEng.length) {
        normalArr.push({
            start: entry.end + 1,
            end: theEng.length - 1, type: "normal", text: theEng.substring(entry.end + 1, theEng.length - 1 + 1)
        })
    } else if (orderBy1[idx + 1] && entry.end + 1 !== orderBy1[idx + 1]?.start) {
        normalArr.push({
            start: entry.end + 1,
            end: orderBy1[idx + 1].start - 1,
            type: "normal",
            text: theEng.substring(entry.end + 1, orderBy1[idx + 1].start - 1 + 1)
        })
    }
})

let finalOrdered = orderBy(orderBy1.concat(normalArr), (aa) => aa.start, "asc");

let aa = [{
    start: 27,
    end: 93,
    type: "top1",
    text: "prompted more than half the inhabitants of the refugee camp to flee"
}]
// enddate = new Date();
// var timeDiffInMs = Math.abs(startdate.getTime() - enddate.getTime());
// let words = getWords(aa[0].text);

// let testStartIdx = theEng.substring(0, aa[0].end + 1).lastIndexOf(words[7]);

let wordsArr = [{startIdx: 36, word: 'more'}, {startIdx: 55, word: 'inhabitants'}, {startIdx: 74, word: 'refugee'}];
wordsArr = orderBy(wordsArr, (theWord) => theWord.startIdx, "asc").map(theWord => {
    return {startIdx: theWord.startIdx, text: theWord.word}
});
wordsArr.forEach(theWord => {
    aa.forEach(thePhrase => {
        if (theWord.startIdx >= thePhrase.start && theWord.startIdx <= thePhrase.end + 1) {
            if (!thePhrase.wordsArr) {
                thePhrase.wordsArr = []
            }
            thePhrase.wordsArr.push(theWord)
        }
    })
})

aa.forEach(thePhrase => {
    let intervalNodeArr = [];
    thePhrase.wordsArr.forEach((theWord, idx) => {
        if (idx === 0 && theWord.startIdx !== thePhrase.start) {
            intervalNodeArr.push({
                startIdx: 0,
                text: theEng.substring(thePhrase.start, theWord.startIdx)
            });
        } else if (idx === thePhrase.wordsArr.length - 1 && (theWord.startIdx + theWord.text.length) !== thePhrase.end + 1) {
            intervalNodeArr.push({
                startIdx: theWord.startIdx + theWord.text.length,
                text: theEng.substring(theWord.startIdx + theWord.text.length, thePhrase.end + 1)
            });
        }

        if (thePhrase.wordsArr[idx + 1]) {
            intervalNodeArr.push({
                startIdx: theWord.startIdx + theWord.text.length,
                text: theEng.substring(theWord.startIdx + theWord.text.length, thePhrase.wordsArr[idx + 1].startIdx)
            });
        }
    })

    let orderedArr = orderBy(intervalNodeArr.concat(thePhrase.wordsArr), theNode => theNode.startIdx, "asc");
    console.log(orderedArr.map(node => node.text).join(""));
})
// "".lastIndexOf()
enddate = new Date();
console.log("ms elapsed 3:", Math.abs(startdate.getTime() - enddate.getTime()));
// console.log(topMostResutlArrs)
// console.log(top1ResutlArrs)
// console.log(resultIntersected)